import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
import {makeBoldLine} from "./MakeBoldLine";

// 基础对象
let width: number;
let height: number;
let renderer: THREE.WebGLRenderer;
let camera: THREE.PerspectiveCamera;
let scene: THREE.Scene;
let wrapper: HTMLElement;

let centerX: number;
let centerY: number;

// 射线检测对象
let raycaster: THREE.Raycaster;

let controls: OrbitControls;

const initThree = () => {
  wrapper = document.getElementById('canvas_wrapper')!;

  width = window.innerWidth;
  height = window.innerHeight;

  renderer = new THREE.WebGLRenderer({antialias: true});

  renderer.setClearColor(0xf0f0f0, 1.0);
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);
  renderer.shadowMap.enabled = true;
  renderer.sortObjects = false;

  wrapper.appendChild(renderer.domElement);

  //
  raycaster = new THREE.Raycaster();
};

const initCamera = () => {
  camera = new THREE.PerspectiveCamera(75, width / height, 1, 2000);
  camera.position.x = 0;
  camera.position.y = 400;
  camera.position.z = -320;

  // 看向
  camera.lookAt(0, 0, 0);
};

const initScene = () => {
  scene = new THREE.Scene();
};

const initLight = () => {
  const directionalLight = new THREE.DirectionalLight('#bdbdbd', 3);
  directionalLight.position.set(-250, 300, -250);

  directionalLight.castShadow = true;

  directionalLight.shadow.mapSize.set(1024, 1024);

  directionalLight.shadow.camera.lookAt(new THREE.Vector3(0, 0, 0));
  directionalLight.shadow.camera.far = 800;
  directionalLight.shadow.camera.left = -200;
  directionalLight.shadow.camera.right = 200;
  directionalLight.shadow.camera.top = 200;
  directionalLight.shadow.camera.bottom = -200;

  scene.add(directionalLight);

  // const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight);
  // scene.add(directionalLightHelper);

  // const directionalLightCameraHelper = new THREE.CameraHelper(directionalLight.shadow.camera);
  // scene.add(directionalLightCameraHelper);

  const light = new THREE.HemisphereLight(0xeeeeff, 0x777788, 0.75);
  light.position.set(0.5, 1, 0.75);
  scene.add(light);
};

const initObjects = () => {

  const result = makeBoldLine([
    new THREE.Vector2(70.0, 10.0),
    new THREE.Vector2(40.0, 10.0),
    new THREE.Vector2(-40, 40),
    new THREE.Vector2(30, 40),
    new THREE.Vector2(-30, -40),
    new THREE.Vector2(40, -40),
    new THREE.Vector2(40, 0),
    new THREE.Vector2(70, 40)
  ], 8);


  const geometry4 = new THREE.BufferGeometry();
  geometry4.setAttribute(
    'position',
    new THREE.BufferAttribute(result.vertices, 2)
  );
  geometry4.setIndex(new THREE.BufferAttribute(result.indexes, 1));
  // geometry4.computeVertexNormals();

  const mesh4 = new THREE.Mesh(
    geometry4,
    new THREE.MeshBasicMaterial({
      color: new THREE.Color('#0055FF'),
      side: THREE.DoubleSide,
    })
  );
  scene.add(mesh4);

  ////////////////////////////////////

  const geometry5 = new THREE.BufferGeometry();
  // 创建一个简单的矩形. 在这里我们左上和右下顶点被复制了两次。
  // 因为在两个三角面片里，这两个顶点都需要被用到。
  const vertices5 = new Float32Array([
    -100.0, -100.0, 100.0, 100.0, -100.0, 100.0, 100.0, 100.0, 100.0,

    100.0, 100.0, 100.0, -100.0, 100.0, 100.0, -100.0, -100.0, 100.0,
  ]);

  // itemSize = 3 因为每个顶点都是一个三元组。
  geometry5.setAttribute('position', new THREE.BufferAttribute(vertices5, 3));
  const material5 = new THREE.MeshBasicMaterial({
    color: 0xff0000,
    side: THREE.DoubleSide,
  });
  const mesh5 = new THREE.Mesh(geometry5, material5);

  scene.add(mesh5);
};


function initHelper() {
  const helper = new THREE.GridHelper(1000, 50, 0x0000ff, 0x808080);
  scene.add(helper);

  const axesHelper = new THREE.AxesHelper(500);
  scene.add(axesHelper);
}

function initControl() {
  controls = new OrbitControls(camera, renderer.domElement);
  // controls.addEventListener('change', render);
  controls.maxPolarAngle = Math.PI / 2;
  controls.enableZoom = true;
  controls.enablePan = true;
  controls.enableDamping = true;
  controls.maxDistance = 580;
  controls.minDistance = 50;
}

function onWindowResize() {
  // console.log('resize');

  centerX = window.innerWidth / 2;
  centerY = window.innerHeight / 2;

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  width = window.innerWidth;
  height = window.innerHeight;
  renderer.setSize(width, height);
}

const animate = (time: number) => {
  requestAnimationFrame(animate);

  render(time);
  // stats.update();

  renderer.render(scene, camera);
};

const render = (time: number) => {
  time *= 0.01;

  controls.update();

  camera.updateProjectionMatrix();
};

let mouseDown = false;
let mouseX = 0;
let mouxeY = 0;

const onMouseDown = (event: PointerEvent) => {
  event.preventDefault();
  mouseDown = true;
  mouseX = event.clientX;
  mouxeY = event.clientY;
};

const onMouseUp = (event: PointerEvent) => {
  event.preventDefault();
  mouseDown = false;
};

const onMouseMove = (event: PointerEvent) => {
  event.preventDefault();
  if (!mouseDown) {
    return;
  }

  mouseX = event.clientX;
  mouxeY = event.clientY;
};

(() => {
  console.log('onLoad');
  initThree();
  // initStats();
  initCamera();
  initScene();
  initLight();

  initObjects();

  initHelper();
  initControl();

  animate(0);

  window.addEventListener('resize', onWindowResize);

})();
